/*
  This ESP8266 Web Socket Emoji Sign based on:
  https://github.com/tzapu/WiFiManager
  https://github.com/Links2004/arduinoWebSockets
*/
#include <EEPROM.h>
#include <avr/pgmspace.h> 
#define WIFI_NAME "matrix-draw"
#define MDNS_NAME "emoji"
#define LED_PIN 4
#define buttonPin   15       //D8
// comment below line for progressive matrix

// Library that help you connect your WiFi AP on the air
#include <WiFiManager.h>

// server libraries
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>
#include "OneButton.h"
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#define NUM_LEDS    256    // 灯珠数
#define xres 16            // Total number of  columns in the display
#define yres 16            // Total number of  rows in the display
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB
// setup server ports
ESP8266WebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(81);
OneButton button(buttonPin, false);
WiFiUDP udp;
NTPClient timeClient(udp, "ntp1.aliyun.com", 60 * 60 * 8, 30 * 60 * 1000);
int Mode;
int color_index;//当前颜色
int brightnessNow;
String  H;
String  M;
String  S;//秒
int D;//星期几 0为周日
bool colon = true;
int colorLoop = 0;

struct ColorRGB{
  int r;
  int g;
  int b;
};

ColorRGB ColorVarInit(int r, int g, int b){
  ColorRGB ex;
  ex.r = r;
  ex.g = g;
  ex.b = b;
  return ex;
}

// setup NePixel
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(xres, yres, 1, 1, LED_PIN,
                            NEO_MATRIX_TOP  + NEO_TILE_LEFT  + NEO_MATRIX_COLUMNS   + NEO_MATRIX_PROGRESSIVE +
                            NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
                            NEO_GRB + NEO_KHZ800);

//RGB颜色数组https://www.sojson.com/rgb.html
const ColorRGB myRGBColorPalette[3][2] = {
  {ColorVarInit(255,255,0), ColorVarInit(255,0,77)},
  {ColorVarInit(0,255,0), ColorVarInit(148,0,211)},
  {ColorVarInit(0,255,255), ColorVarInit(255,0,255)}
};
  
String bitdata20[10]={
  "111101101101111","010110010010111",
  "111001111100111","111001111001111",
  "101101111001001","111100111001111",
  "111100111101111","111001001001001",
  "111101111101111","111101111001111"
};


// handle WebSocket message
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  switch (type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED: {
        IPAddress ip = webSocket.remoteIP(num);
        //Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        // send message to client
        webSocket.sendTXT(num, "Connected");
      }
      break;
    case WStype_TEXT:
      Serial.printf("[%u] get Text[%u].\n", num, length);

      String txt = String();
      Serial.println(*payload);
      uint8_t i = 0;
      for (uint8_t y = 0; y < yres; y++) {
        for (uint8_t x = 0; x < xres; x++) {
          uint8_t r = payload[y*16*3+x*3]*2;
          uint8_t g = payload[y*16*3+x*3+1]*2;
          uint8_t b = payload[y*16*3+x*3+2]*2;
          matrix.drawPixel(x,y,matrix.Color(r,g,b));
          Serial.printf("(%u, %u) color: %u, %u, %u\n", x, y, r, g, b);
        }
      }
      matrix.show(); // This sends the updated pixel color to the hardware.
      break;
  }
}

void setup() {
  Serial.begin(115200);
  EEPROM.begin(512);
  // Check if this is first time EEPROM is used
  
  matrix.begin();
  matrix.setTextWrap(false);
  matrix.setBrightness(brightnessNow);
  matrix.show(); // This sends the updated pixel color to the hardware.

  //WiFiManager
  WiFiManager wifiManager;
  wifiManager.autoConnect(WIFI_NAME);
  // start MDNS
  if (MDNS.begin(MDNS_NAME)) {
    Serial.println("MDNS responder started.");
  }
  button.attachClick(colorChange);
  button.attachDoubleClick(modeChange);
  button.attachMultiClick(statusSave);
  button.attachDuringLongPress(brightnessChange);
  // start web server
  // handle index
  server.on("/", []() {
    // send index.html
    server.send(200, "text/html", "<!DOCTYPE html><html><head>    <meta name='viewport' content='user-scalable=no,initial-scale=2.0' />    <style>        body {            background: #000;            color: #fff;            text-align: center        }        div {            margin: 10px        }    </style></head><body>    <div>        <h3>Pick An Emoji</h3> <img id='emojis' onclick='clickEmoji(event);'            src=''>    </div>    <div>        <p id='out'></p> <canvas id='emoji' width='8' height='8'></canvas>    </div>    <script>    function nw() { return new WebSocket('ws://' + location.hostname + ':81/', ['arduino']); } var ws = nw();     var sk = 0;    function cc(c) { return String.fromCharCode(c / 2); }    function clickEmoji(e) {         var xo = 3; var yo = 3; var xs = 13; var ys = 12; var x = e.offsetX; var y = e.offsetY;         var c = Math.round((x - xo - 4) / xs);         var r = Math.round((y - yo - 4) / ys);         document.getElementById('out').innerText = 'Selected [' + c + ', ' + r + ']';         var img = document.getElementById('emojis');         var ce = document.getElementById('emoji');         var ctx = ce.getContext('2d');         ctx.drawImage(img, -(xo + (xs * c)), -(yo + (ys * r)), 131, 122);        var d = ctx.getImageData(0, 0, 16, 16).data;         var t = '';         for (var i = 0; i < 16; i++)        {            for(var j = 0; j < 16; j++){                var x = parseInt((j+2)/2)-1;                var y = parseInt((i+2)/2)-1;                var imageData = ctx.getImageData(x, y, 1, 1).data;                t += cc(imageData[0]);                t += cc(imageData[1]);                t += cc(imageData[2]);            }        }        ws.send(t, { binary: true }); }    </script></body></html>");
    Serial.println("index.html sent.");
  });
  server.begin();

  // start webSocket server
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
  // Add service to MDNS
  MDNS.addService("http", "tcp", 80);
  MDNS.addService("ws", "tcp", 81);
  if (EEPROM.read(256) != 123) {  // not equal to 123
    Serial.println("未查到默认配置");
    Mode = 0;
    color_index = 0;
    brightnessNow = 50;
  } else {  // if byte 256 is equal to 123
    Serial.println("存有默认配置");
    Mode = int(EEPROM.read(0));  // get previous lit leds before power failure
    color_index = int(EEPROM.read(1));
    brightnessNow = int(EEPROM.read(2));
  }
  matrix.setBrightness(brightnessNow);
  matrix.show();
  switchMode(true);
}

unsigned long lastTime = 0;
unsigned long lastColorTime = 0;
unsigned int counter = 0;
//模式变更
void modeChange()
{
  matrix.clear();
  matrix.show();
  if (++Mode > 2)Mode = 0;//模式变化
  Serial.println("按键切换模式");
  Serial.println(Mode);
  switchMode(true);
}
//颜色模式变更
void colorChange()
{
  if (++color_index > 2)color_index = 0;//模式变化
  Serial.println("按键切换颜色");
  Serial.println(color_index);
  switchMode(true);
}
//亮度调节
void brightnessChange()
{
  unsigned long t = millis();
  if ((t - lastTime) > 500) {
    brightnessNow += 10;
    if(brightnessNow > 100){
      brightnessNow = 10;
    }
    matrix.setBrightness(brightnessNow);
    matrix.show();
    lastTime = millis();
  }
}
//设置保存
void statusSave(){
  Serial.println("按键保存配置");
  if (EEPROM.read(256) != 123) {  // not equal to 123
    EEPROM.write(256, 123);  // write value 123 to byte 256
    EEPROM.write(0, Mode);
    EEPROM.write(1, color_index);
    EEPROM.write(2, brightnessNow);
  } else {  // if byte 256 is equal to 123
      EEPROM.write(0, Mode);
      EEPROM.write(1, color_index);
      EEPROM.write(2, brightnessNow);
  }
  EEPROM.commit();
  int x = xres;
  for(int i=0;i<36;i++){
    matrix.clear();
    matrix.fillScreen(0);
    matrix.setCursor(x, 4);
    matrix.print(F("Saved"));
    matrix.setTextColor(matrix.Color(148,0,211));
    if(--x < -36) {
      x = matrix.width();
    }
    matrix.show();
    system_soft_wdt_feed();
    delay(70);
  }
  matrix.clear();
  switchMode(true);
}

const uint8_t pikachu1[] PROGMEM = {0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,232,232,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,255,242,0,20,20,20,20,20,20,20,20,20,255,242,0,255,242,0,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,232,232,232,232,232,232,232,232,232,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,255,0,0,255,0,0,255,0,0,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,232,232,232,232,232,232,20,20,20,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,232,232,232,232,232,232,20,20,20,232,232,232,232,232,232,20,20,20,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,0,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,20,20,20,0,0,185,20,20,20,20,20,20,232,232,232,232,232,232,232,232,232,143,12,18,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,20,20,20,45,45,0,45,45,0,45,45,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,0,0,185,0,0,185,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,45,45,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,0,0,185,20,20,20,232,232,232,232,232,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,20,20,20,45,45,0,45,45,0,45,45,0,255,242,0,255,242,0,20,20,20,20,20,20,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,0,0,185,20,20,20,232,232,232,232,232,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,45,45,0,45,45,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,45,45,0,45,45,0,45,45,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,0,0,0,0,0,0,0,0,0,0,0,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232};
const uint8_t pikachu2[] PROGMEM = {0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,255,242,0,20,20,20,20,20,20,20,20,20,255,242,0,255,242,0,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,232,232,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,255,0,0,255,0,0,255,0,0,255,0,0,255,0,0,232,232,232,232,232,232,232,232,232,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,255,0,0,255,0,0,255,0,0,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,255,242,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,232,232,232,232,232,232,20,20,20,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,255,0,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,232,232,232,232,232,232,20,20,20,232,232,232,232,232,232,20,20,20,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,20,20,20,45,45,0,45,45,0,45,45,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,45,45,0,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,0,0,185,20,20,20,20,20,20,232,232,232,232,232,232,232,232,232,143,12,18,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,20,20,20,45,45,0,45,45,0,45,45,0,255,242,0,255,242,0,20,20,20,20,20,20,255,242,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,0,0,185,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,232,232,232,232,232,232,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,20,20,20,20,20,20,255,242,0,255,242,0,255,242,0,255,242,0,20,20,20,255,242,0,255,242,0,20,20,20,0,162,232,0,162,232,20,20,20,45,45,0,20,20,20,232,232,232,232,232,232,20,20,20,45,45,0,45,45,0,20,20,20,45,45,0,45,45,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,255,242,0,255,242,0,20,20,20,20,20,20,20,20,20,20,20,20,0,162,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,20,20,20,45,45,0,45,45,0,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,45,45,0,45,45,0,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,20,20,20,20,20,20,20,20,20,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232,0,162,232};
const uint8_t kabi[] PROGMEM = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,64,128,224,96,128,224,96,128,224,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,64,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,64,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,96,128,224,96,128,224,96,128,0,0,0,224,96,128,224,96,128,0,0,0,224,96,128,224,96,128,224,96,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,64,128,224,96,128,224,96,128,224,96,128,255,255,255,224,96,128,224,96,128,255,255,255,224,96,128,224,96,128,224,96,128,224,64,128,0,0,0,0,0,0,0,0,0,0,0,0,224,96,128,224,96,128,224,96,128,224,96,128,0,0,0,224,96,128,224,96,128,0,0,0,224,96,128,224,96,128,224,96,128,224,96,128,0,0,0,0,0,0,0,0,0,0,0,0,224,96,128,224,96,128,224,96,128,224,96,128,0,0,100,224,96,128,224,96,128,0,0,100,224,96,128,224,96,128,224,96,128,224,96,128,0,0,0,0,0,0,0,0,0,0,0,0,224,64,128,224,96,128,224,0,64,224,0,64,224,96,128,224,96,128,224,96,128,224,96,128,224,0,64,224,0,64,224,96,128,224,64,128,0,0,0,0,0,0,0,0,0,224,0,64,224,0,64,224,96,128,224,96,128,224,96,128,224,96,128,0,0,0,0,0,0,224,96,128,224,96,128,224,96,128,224,96,128,224,0,64,224,0,64,0,0,0,0,0,0,224,0,64,224,0,64,224,64,128,224,96,128,224,96,128,224,96,128,224,0,64,224,0,64,224,96,128,224,96,128,224,96,128,224,64,128,224,0,64,224,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,64,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,96,128,224,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,32,128,224,0,64,224,0,64,224,0,64,224,64,128,224,96,128,224,96,128,224,64,128,224,0,64,224,0,64,224,0,64,224,32,128,0,0,0,0,0,0,0,0,0,0,0,0,224,0,64,224,0,64,192,0,64,192,0,64,0,0,0,0,0,0,0,0,0,0,0,0,192,0,64,192,0,64,224,0,64,224,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

int z = 0;//平移坐标
int zres = 62;//动画像素长度(高度默认与yres一致)
int rate = 200;

//显示画板功能
void showDrawingBoard(bool implement) {
  MDNS.update();
  unsigned long t = millis();
  webSocket.loop();
  server.handleClient();
  if(implement){
    matrix.clear();
    showKabi();
    matrix.show();
  }
  if ((t - lastTime) > 10 * 1000 | implement) {
    counter++;
    bool ping = (counter % 2);
    int i = webSocket.connectedClients(ping);
    Serial.printf("%d Connected websocket clients ping: %d\n", i, ping);
    lastTime = millis();
  }
}

//显示时间
void showTime(bool implement)
{
  timeClient.update();
  H = timeClient.getFormattedTime().substring(0, 2);
  M = timeClient.getFormattedTime().substring(3, 5);
  S = timeClient.getFormattedTime().substring(6, 8);
  D = timeClient.getDay();
  if ( millis() - lastTime > 1000 | implement)
  {
    if(!implement){
      lastTime = millis();
    }
    if(colon){
      colon = false;
    }else{
      colon = true;
    }
  }
  if ( millis() - lastColorTime > 200 | implement)
  {
    if(!implement){
      lastColorTime = millis();
    }
    colorLoop = colorLoop+1;
      if(colorLoop>60){
        colorLoop = 1;
    }
    showbitnumber(H,3,5,1,9);
    showbitnumber(M,3,5,9,9);
    showbitnumber(S,3,5,5,1);
    //冒号
    //showColon(12,2,colon);
    //showColon(12,12,colon);
    matrix.show();
  }
}

void showColon(int x,int y,bool l){
    if(l){
      matrix.drawPixel(x,y,Gradient(x,y));
    }else{
      matrix.drawPixel(x,y,matrix.Color(0, 0, 0));
    }
}

void showbitnumber(String number, int xlength, int ylength, int x, int y){
  if(number.toInt()<10){
    showbitmap(bitdata20[(int)(0)],xlength,ylength, x, y);
    showbitmap(bitdata20[(int)((String(number.charAt(1)).toInt() + 1) - 1)],xlength,ylength, x+4, y);
  }else if(number.toInt()<100){
    showbitmap(bitdata20[(int)((String(number.charAt(0)).toInt() + 1) - 1)],xlength,ylength, x, y);
    showbitmap(bitdata20[(int)((String(number.charAt(1)).toInt() + 1) - 1)],xlength,ylength, x+4, y);
  }
}

void showbitmap(String bitrgbstr, int xlength, int ylength, int x, int y) {
  //Serial.println("bitrgbstr = " + bitrgbstr);
  for (int i = x; i < x+(xlength); i = i + (1)) {
    for(int j = y; j < y+(ylength); j = j + (1)){
      if (String(bitrgbstr.charAt(((j-y)*xlength+i-x))).toInt() != 0) {
        matrix.drawPixel(i,j,Gradient(i,j));
      } else {
        matrix.drawPixel(i,j,matrix.Color( 0, 0, 0));
      }
    }
  }
}

void showKabi(){
    for (uint8_t y = 0; y < yres; y++) {
          for (uint8_t x = 0; x < xres; x++) {
              uint8_t r = pgm_read_dword(&(kabi[y*xres*3+x*3]));
              uint8_t g = pgm_read_dword(&(kabi[y*xres*3+x*3+1]));
              uint8_t b = pgm_read_dword(&(kabi[y*xres*3+x*3+2]));
              matrix.drawPixel(x,y,matrix.Color(r,g,b));
          }
    }  
}

void showCartoon(){
  if ( millis() - lastTime > rate )
  {
    lastTime = millis();
    if(z%2==0){
      for (uint8_t y = 0; y < yres; y++) {
          for (uint8_t x = 0; x < xres; x++) {
              uint8_t r = pgm_read_dword(&(pikachu2[y*zres*3+(x+zres-xres-z)*3]));
              uint8_t g = pgm_read_dword(&(pikachu2[y*zres*3+(x+zres-xres-z)*3+1]));
              uint8_t b = pgm_read_dword(&(pikachu2[y*zres*3+(x+zres-xres-z)*3+2]));
              matrix.drawPixel(x,y,matrix.Color(r,g,b));
          }
      }
    }else{
      for (uint8_t y = 0; y < yres; y++) {
          for (uint8_t x = 0; x < xres; x++) {
              uint8_t r = pgm_read_dword(&(pikachu1[y*zres*3+(x+zres-xres-z)*3]));
              uint8_t g = pgm_read_dword(&(pikachu1[y*zres*3+(x+zres-xres-z)*3+1]));
              uint8_t b = pgm_read_dword(&(pikachu1[y*zres*3+(x+zres-xres-z)*3+2]));
              matrix.drawPixel(x,y,matrix.Color(r,g,b));
          }
      }
    }
    matrix.show();
    z = (z+1)%(zres-xres);
  }
}

//渐变色颜色计算方法
uint16_t Gradient(int x, int y){
  ColorRGB A = myRGBColorPalette[color_index][0];
  ColorRGB B = myRGBColorPalette[color_index][1];
  int n = 0;
  if(colorLoop<31){
    if(x+y>colorLoop){
      n = x+y-colorLoop;
    }else{
      n = colorLoop-x-y;
    }
  }else{
    if(x+y>(colorLoop-30)){
      n = 30-(x+y-colorLoop+30);
    }else{
      n = 30-(colorLoop-30-x-y);
    }
  }
  int r = (B.r-A.r)/30*n+A.r;
  int g = (B.g-A.g)/30*n+A.g;
  int b = (B.b-A.b)/30*n+A.b;
  return matrix.Color(r,g,b);

}

void switchMode(bool change){
  switch (Mode)
  {
    case 0:
      showTime(change);
      break;
    case 1:
      showDrawingBoard(change);
      break;
    case 2:
      showCartoon();
      break;
  }
}

void loop()
{
  button.tick();
  switchMode(false);
}
